﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace M
{
	/// <summary>
	/// 通用的Wcf Client
	/// </summary>
	public static class WcfClientProxy
	{
		/// <summary>
		/// 执行
		/// </summary>
		/// <typeparam name="TClient">WcfClientBase</typeparam>
		/// <typeparam name="TResult">服务方法返回类型</typeparam>
		/// <param name="act"></param>
		/// <returns></returns>
		public static TResult Invoke<TClient, TResult>(Expression<Func<TClient, TResult>> act)
		  where TClient : System.ServiceModel.ICommunicationObject, new()
		{
			TClient client = new TClient();
			return client.Invoke<TClient, TResult>(act);
		}
		/// <summary>
		/// 执行
		/// </summary>
		/// <typeparam name="TClient">WcfClientBase</typeparam>
		/// <param name="act"></param>
		public static void Invoke<TClient>(Action<TClient> act)
			where TClient : System.ServiceModel.ICommunicationObject, new()
		{
			new TClient().Invoke(act);
		}
		/// <summary>
		/// 执行
		/// </summary>
		/// <typeparam name="TClient">WcfClientBase</typeparam>
		/// <param name="client">Client实例</param>
		/// <param name="act"></param>
		public static void Invoke<TClient>(this TClient client, Action<TClient> act)
			where TClient : System.ServiceModel.ICommunicationObject, new()
		{
			try
			{
				act(client);
				client.Close();
			}
			catch (System.ServiceModel.CommunicationObjectFaultedException)
			{
				client.Abort();
			}
			catch (System.ServiceModel.CommunicationException)
			{
				client.Abort();
				throw;
			}
			catch (TimeoutException)
			{
				client.Abort();
				throw;
			}
			catch (Exception)
			{
				client.Abort();
				throw;
			}
		}
		/// <summary>
		/// 执行
		/// </summary>
		/// <typeparam name="TClient">WcfClientBase</typeparam>
		/// <typeparam name="TResult">服务方法返回类型</typeparam>
		/// <param name="client">Client实例</param>
		/// <param name="act"></param>
		/// <returns></returns>
		public static TResult Invoke<TClient, TResult>(this TClient client, Expression<Func<TClient, TResult>> act)
		  where TClient : System.ServiceModel.ICommunicationObject, new()
		{
			Func<TClient, TResult> fun = act.Compile();
			TResult result = default(TResult);
			try
			{
				result = fun.Invoke(client);
				client.Close();
			}
			catch (System.ServiceModel.CommunicationObjectFaultedException)
			{
				client.Abort();
			}
			catch (System.ServiceModel.CommunicationException)
			{
				client.Abort();
				throw;
			}
			catch (TimeoutException)
			{
				client.Abort();
				throw;
			}
			catch (Exception)
			{
				client.Abort();
				throw;
			}
			return result;
		}
	}
}
